local desc_wjsl_mode = [[
  # 巅峰神塔简介
  ___

  搬运自huosan服大佬
  人数：2~6人，需要手动配置至少1个人机作为塔层层主，1-4人玩家

  胜利条件：玩家通关第71层。

  失败条件：玩家全部死亡或者投降。玩家自由选将不在白名单列表。玩家与人机比最多3：1超过则游戏结束

  层主技能：1.随机技能：除了武将自身技能还会有额外随机技能，每次层主复活会获得额外随机技能。2.关卡技能：层主会根据你所在层数获得永久不变的技能

  神将层主：实力远高于层主，击败后获得其神将身上任意一个技能。

  卡牌：无视开启的扩展卡组。会自动过滤其他卡组，只留下标准包，军争包，浪包。

  武将扩展包：无视开启的扩展包，只从白名单中随机12个武将任意选1个。白名单为欢杀全将池（不包括神将）。

  规则：冲塔层数，击败神将。到达神塔巅峰71层。每层对抗白名单将池内随机的武将（不重复）。有且只有1名层主，其他人机武将皆为层主队友。当每次击杀层主，塔层层数+1且层主在白名单将池内随机替换1名武将复活，复活后重置武将弃所有牌并重置标记、重置状态；层主根据层数获得随机技能、最大体力、初始手牌；强度呈线性增长

  玩家击败层主后会根据不同层数获得选项增益。增益包括【随机的永久技能】，【随机的最大体力值上限】，【随机的金币】，【摸一定数量的牌】，【潘多拉】（随机事件），【幸运】（下次选项+1且多选+1），【杀】或【锦囊】伤害加成，【守护天使】（复活甲设定）等。

  多人玩家（2-4名玩家）：每位玩家获得【咆哮】【铸甲】技能，层主获得【镇塔】【咆哮】技能。

  【铸甲】：出牌阶段限制（层数/10|向上取整）* 2次。你可以重铸1张【闪】或者【装备】牌，也可以丢弃两张【闪】或【装备】牌获得1枚护甲（最多为5护甲）直到你下回合开始时失去以此法获得数量的护甲。

  【镇塔】：锁定技，每名角色回合开始时，使用牌会计入次数，计数为最大体力值的两倍（当最大体力值超过5，计数只+1且最多为15），使用卡牌结算后或者因【铸甲】获得护甲，计数-1。当计数为0时结束当前阶段。

]]

--是否开启写入武将白名单
local iswrigenlist = false
--开启测试
local istest = false
--测试AI武将（避免自由选）
local testgens = {"zhangxiu","nya__wangyi","zhugeke","zhoubuyi","ol__tengfanglan","dongyun","l__zhangliao","ex__simayi","ol_ex__zhangjiao","ty_ex__zhuran","l__lvbu","ty__yanghu","zhaotongzhaoguang","joy__xunyou","miniex__huangyueying","ty__yanghu","joy__xunyou","joy__godzhaoyun","js__guanyu","lvlingqi","dukui","ty_ex__wuyi","ol_ex__sunjian","xizhicai","qinmi","godganning","ty__chenlin","ex__ganning","yuejiu","caomao","ty__lidian","ol__luyusheng","godganning","ty_ex__caozhi","zhaotongzhaoguang"}
--ai队友身份(默认主公队友也就是忠臣loyalist，改反的话变为rebel)
local aifriendrole = "rebel"
--精选热门武将不必自由选
local hotgenerals = {}
--过滤其他卡组（只允许白名单的卡组加入牌堆）
local whilecards = {"standard","standard_cards","maneuvering","lang_cards","tenyear_token","mobile_derived","ol_token","overseas_token","joy_token","fuzhi_cards","fuzhi2_cards",}
--保留玩家本模式重要的标记
local savemarks = {"curlayerphase","@slash_dmg","@trick_dmg","@pdlbox","@gold_num","@df_lingxin","@shieldnum","tshu__buff1","tshu__buff2","tshu__buff3","tshu__buff4","tshujl__zhugeguo","tshujl__lingjv","tshujl__zhouyu","tshujl__caoying","tshujl__guansuo","tshujl__nianshou","tshujl__zhaoxiang","tshujl__xiaosha","tshujl__caochun","tshujl__guanyu"}
--固定将框
local aogeng = {"joy__laiyinger","joy_mou__machao","joy__chengong","joy__zhugedan","joy__zhaoxiang","joy__quyi",}
--浦沅商店
local shop_items = {"sp_redpotion:::170","sp_bluepotion:::130",--这1排2个药水
"st_red_spear:::90", "st_quenched_blade:::110", "st_poisonous_dagger:::140", "st_water_sword:::120","st_thunder_blade:::115","st_fm_jingang:::120","st_sw_feijiang:::115","st_xyd_xueyingdao:::110",--这1排8个装备
"sk_joy_mou__tieji:::180","sk_zuowei:::120","sk_zhenqiao:::110","sk_js__zhubei:::90","sk_l_wuqian:::100","sk_joysp__paoxiao:::125","sk_zhihengs:::60","sk_joyex__lieren:::80",
"sk_guanjue:::170","sk_joy__baobian:::150","sk_joyex__dangxian:::200","sk_mini__kuanggu:::160","sk_l_liezhen:::90","sk_baichu:::80","sk_xiongmu:::200","sk_joyex__zhiheng:::140", --这两排16个进攻技能
"sk_cangxin:::140","sk_ol_ex__weimu:::120","sk_jueyong:::80","sk_xiangle:::60","sk_shoushu:::110","sk_huituo:::80","sk_joy__shushen:::70","sk_zhendan:::60",
"sk_joyex__shangshi:::70","sk_os__liechi:::100","sk_shixin:::40","sk_ol_ex__buqu:::70","sk_m_ex__sidi:::50","sk_mini__keji:::150","sk_joy__guanwei:::100","sk_ol__zhouxuan:::70",
"sk_lvli:::60","sk_joyex__jueqing:::200","sk_jincui:::230","sk_kuangcai:::130","sk_joyex__guicai:::100","sk_joy__manwang:::80","sk_joy__pingjian:::50","sk_chenglve:::60", 
"sk_tongye:::50","sk_chengxu:::50","sk_ex__longdan:::120",} --这4排26个防御技能

local shop_items_trans = {sp_redpotion = "愤怒药水",sp_bluepotion = "冥想药水",
st_red_spear = "红缎枪",st_quenched_blade = "烈淬刀",st_poisonous_dagger = "混毒弯匕",st_water_sword = "水波剑",
st_thunder_blade = "天雷刃",st_fm_jingang = "伏魔金刚杵",st_sw_feijiang = "神威飞将剑",st_xyd_xueyingdao = "血影刀",
sk_joy_mou__tieji = "谋铁骑",sk_zuowei = "作威",sk_zhenqiao = "振鞘",sk_js__zhubei = "逐北",sk_l_wuqian="浪无前",sk_joysp__paoxiao="SP咆哮",sk_zhihengs="猘横",sk_joyex__lieren="界烈刃",sk_chengxu="乘虚",
sk_ex__longdan="界龙胆",sk_cangxin="藏心",sk_guanjue="冠绝",sk_ol_ex__weimu="OL界帷幕",sk_jueyong="绝勇",sk_shoushu="授术",sk_huituo="恢拓",sk_joy__shushen="淑慎",sk_zhendan="镇胆",sk_joyex__shangshi="界伤逝",
sk_os__liechi="烈斥",sk_xiangle="享乐",sk_shixin="释衅",sk_ol_ex__buqu="界不屈",sk_m_ex__sidi="界司敌",sk_xiongmu="雄幕",sk_mini__kuanggu="mini狂骨",sk_mini__keji="mini克己",sk_joyex__zhiheng="界制衡",sk_joy__guanwei="观微",
sk_l_liezhen="裂阵",sk_baichu="百出",sk_ol__zhouxuan="OL周旋",sk_lvli="膂力",sk_joyex__jueqing="界绝情",sk_jincui="尽瘁",sk_joyex__dangxian="界当先",sk_joy__baobian="豹变",sk_kuangcai="新狂才",sk_joyex__guicai="界鬼才",
sk_joy__manwang="蛮王（弃牌技）",sk_joy__pingjian="评鉴",sk_chenglve="成略",sk_tongye="统业"}
local shop_trans = {}
for _,item in ipairs(shop_items) do
  local pos = string.find(item,":")
  local trans_key = string.sub(item,1,pos-1)
  local trans = shop_items_trans[trans_key]
  shop_trans[trans_key] = trans.."(%arg金币)"
end
Fk:loadTranslationTable(shop_trans)

--初始化游戏数据
local initGameData = {
  i_layer = 1,--初始关卡
  t_layer = 71,--总关卡
  initgold = 5,--初始金币
  maxctiwin = 5,--连胜最多次数即中断当前玩家阶段
  laygetskill_n = 4,--层主每过几关获得技能
  rewd_intval = {{18,1,4},{32,2,5},{100,3,6}}, --关卡选项变化（可以多选与加选）
  layownskills = {mashu = 6,l_wuqian = 11,os_ex__paoxiao = 17,langxi = 24,wjsl_tazhen = 31,liji = 41,qianjie = 51,joyex__shangshi = 71}, --层主关卡技能
  rewards = {gaingold=0.1,skills = 0.1,maxhp = 0.1,lingxin = 0.1,magicbox=0.1,angelbless=0.1,slash_dmg_sel=0.1,trick_dmg_sel=0.1,shieldnum = 0.1},--玩家奖励概率配置
  rulename = "#wjsl_rule", --游戏模式名
  godboss = {"joy__godzhouyu","joy__godzuoci", "joy__godliubei","joy__goddiaochan","joy__godzhenji","joy__goddaxiaoqiao","joy__godhuatuo","joy__goddianwei","joy__godzhaoyun", "joy__godganning","joy__godguanyu","joy__godcaocao", "joy__godtaishici","joy__godlvbu","joy__godlvmeng","joy__godzhangliao","joy__godsunquan","joy__godmachao","joy__godzhangjiao","joy__godjiangwei","joy__godxunyu","joy__godsunce","joy__godguojia","joy__godluxun"},--神将boss
  hardmodel = "hardmodel",--默认困难难度
  shopitems = shop_items --商店物品
}

EndLessPractice = require "packages/joymode/EndLessPractice"

local wjsl_getLogic = function()
  local wjsl_logic = GameLogic:subclass("wjsl_logic")

  function wjsl_logic:initialize(room)
    GameLogic.initialize(self, room)
    self.role_table = {
      { "lord" },
      { "lord", "rebel" },
      { "lord", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel" },
    }
  end

  function GameLogic:prepareForStart()
    local room = self.room
    local players = room.players
    self:addTriggerSkill(GameRule)
    for _, trig in ipairs(Fk.global_trigger) do
      if trig.name ~= "mobile_effect" then  --关闭手杀特效
        self:addTriggerSkill(trig)
      end
    end
    self.room:sendLog{ type = "$GameStart" }
  end

  function wjsl_logic:prepareDrawPile()
    local room = self.room
    --重新过滤卡组
    local filterCardIds = {}
    local allCardIds = Fk:getAllCardIds()
    for i = 1, #allCardIds do
      local id = allCardIds[i]
      local card = Fk:getCardById(id)
      if card then
        if card.is_derived then
          table.insert(room.void, id)
          room:setCardArea(id, Card.Void, nil)
        else
          if table.contains(whilecards,card.package.name) then
            table.insert(filterCardIds,id)
          end
        end
      end
    end
    table.shuffle(filterCardIds)
    room.draw_pile = filterCardIds
    for _, id in ipairs(room.draw_pile) do
      room:setCardArea(id, Card.DrawPile, nil)
    end
  end

  function wjsl_logic:assignRoles()
    local room = self.room
    local n = #room.players
    local roles = self.role_table[n]
    table.shuffle(roles)

    local bots_t = {}
    local players_t = {}
    for i = 1, n do
      local p = room.players[i]
      if p.id < 0 then
        table.insert(bots_t,{p.id,i})
      end
      if p.id > 0 then
        table.insert(players_t,{p.id,i})
      end
    end

    if #bots_t >= 1 then
      local botsrand_t = table.random(bots_t)
      local bot_player = room.players[botsrand_t[2]]
      bot_player.role = "lord"
      bot_player.role_shown = true
      room:broadcastProperty(bot_player, "role")
    
      for i = 1, n do
        local p = room.players[i]
        if p.role ~= "lord" then
          if p.id < 0 then
            p.role = aifriendrole
            -- p.role = "rebel"
          else
            p.role = "rebel"
          end
          p.role_shown = true
          room:notifyProperty(p, p, "role")
        end
      end
    else
      --默认主反模式
      for i = 1, n do
        local p = room.players[i]
        p.role = roles[i]
        if p.role == "lord" then
          p.role_shown = true
          room:broadcastProperty(p, "role")
        else
          room:notifyProperty(p, p, "role")
        end
      end
    end
  end

  function wjsl_logic:chooseGenerals()
    local room = self.room
    local lord = room:getLord()
    room.current = lord
    local nonlord = room.players

    self.endlPrac = nil
    self.endlPrac = EndLessPractice:new()
    self.endlPrac.all_generals = {}
    self.endlPrac.clone_generals = {}
    local w_gs
    if iswrigenlist then
      w_gs = io.open("packages\\joymode\\white_generals.txt","w")
      -- w_gs:write("")
    end
    local totalgens = Fk.generals
    local tgens = GensLimts:getToTalGens()
    local selct_gs = {}
    for _, gen in ipairs(tgens) do
      local g = totalgens[gen]
      if g then
        table.insert(self.endlPrac.all_generals,g)
        table.insert(self.endlPrac.clone_generals,g)
        if iswrigenlist then
          local str = Fk:translate(g.name).."..来源于扩展包:".."【"..Fk:translate(g.package.name).."】".."\n"
          w_gs:write(str)
        end
      end
    end
    if iswrigenlist then w_gs:close() end
    local clohotgens = table.clone(hotgenerals)
    clohotgens = table.random(clohotgens,6)
    table.insertTable(clohotgens,table.map(table.random(self.endlPrac.all_generals,12),function(gen) 
      return gen.name 
    end))
    table.shuffle(clohotgens)
    table.shuffle(self.endlPrac.all_generals)
    local generalNum = 12
    local testgs = table.clone(testgens)
    for _, p in ipairs(nonlord) do
      local arg = {}
      if p.id > 0 then
        for i = 1, generalNum do
          local g = clohotgens[i]
          if g then
            table.insert(arg, g)
          end
        end
        if istest then
          table.insert(arg, "mouxusheng")
        end
        for _, name in ipairs(aogeng) do
          if not table.contains(arg,name) then
            table.insert(arg,name)
          end
        end
      else
        if istest then
          local autoselgen = #testgs > 0 and table.remove(testgs,1) or table.remove(self.endlPrac.all_generals,1)
          if autoselgen then table.insert(arg, autoselgen.name or autoselgen) end
        else
          local autoselgen = table.remove(self.endlPrac.all_generals,1)
          if autoselgen then table.insert(arg, autoselgen.name) end
        end
      end
      p.request_data = json.encode({ arg, 1 })
      p.default_reply = arg[1]
    end

    room:doBroadcastRequest("AskForGeneral", nonlord)
    for _, p in ipairs(nonlord) do
      if p.general == "" and p.reply_ready then
        local general = json.decode(p.client_reply)[1]
        room:setPlayerGeneral(p, general, true, true)
      else
        room:setPlayerGeneral(p, p.default_reply, true, true)
      end
      p.default_reply = ""
    end

    --room:askForChooseKingdom(nonlord)
    for _, p in ipairs(nonlord) do
      room:broadcastProperty(p, "general")
      if p.role == "lord" then
        room:broadcastProperty(p, "kingdom")
      end
    end
  end
  return wjsl_logic
end

local rm_general = function (generals,g)
  for i = 1, #generals do
    if g.general == generals[i].name then
      table.remove(generals,i)
      return true
    end
  end
  return false
end

--巅峰神塔模式
local wjsl_rule = fk.CreateTriggerSkill{
  name = "#wjsl_rule",
  priority = 0.001,
  refresh_events = {fk.GameStart,fk.BuryVictim,fk.GameOverJudge,fk.TurnStart,fk.DrawNCards},
  can_refresh = function(self, event, target, player, data)
    if event == fk.TurnStart then
      return player == target
    else
      return player.id < 0 and player.role == "lord"
    end
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.BuryVictim then
      room:setTag("SkipGameRule", true)
      local body = room:getPlayerById(data.who)
      local lord = player.room:getLord()
      local logic = lord.room.logic
      local endlPrac = logic.endlPrac
      local allgenerals = endlPrac.all_generals
      local clonegenerals = endlPrac.clone_generals
      if not target.dying then return end
      if not allgenerals or #allgenerals == 0 then
        room:doBroadcastNotify("ShowToast", "将池耗尽")
        room:gameOver("rebel")
        return
      end
      --过了所有关卡胜利
      local curlayer = endlPrac:getLayer()
      if curlayer >= endlPrac.totallayer then
        if endlPrac.totallayer == 71 then
          room:doBroadcastNotify("ShowToast", "最终层！！爬塔成功！！可喜可贺！！！")
          room:gameOver("rebel")
          return
        else
          room:doBroadcastNotify("ShowToast", endlPrac.totallayer.."层！！爬塔成功！！可喜可贺！！！")
          room:gameOver("rebel")
          return
        end
      end
      --层主忠臣队友阵亡处理
      if body.role == "loyalist" and body.id < 0 then
        endlPrac:addContiWin(1)
        endlPrac:bury(body)
        local draw = 2 + math.floor(curlayer / 10)
        room:drawCards(lord, draw,self.name)
        endlPrac:otherPlayersDraw(draw)
        endlPrac:handleContiWin()
        return
      end
      --玩家阵亡处理
      if body.role == "rebel" then
        --守护天使效果
        if body:getMark("@@guardangle") > 0 then
          endlPrac:bury(body,savemarks)
          room:revivePlayer(body, false)
          room:drawCards(body, 4 + (math.floor(curlayer/10) * 2),self.name)
          if room.current.role ~= body.role then
            endlPrac:endWhoPhase(room.current,GameEvent.ChangeHp,true)
          end
          return
        end
        --全部阵亡结算
        local samecamps = endlPrac:getOPlayers(player)
        if #samecamps <= 0 then
          room:doBroadcastNotify("ShowToast", "全部阵亡，爬塔层数"..curlayer)
          room:gameOver("lord")
          return
        end
        --玩家阵亡处理
        endlPrac:bury(body,savemarks)
        endlPrac:otherPlayersDraw(1+(math.floor(curlayer/10)*2))
        room:doBroadcastNotify("ShowToast", Fk:translate(body.general) .."阵亡，别放弃还有机会复活")
        return
      end
      --boss死亡后获得其中一个技能
      local defeat
      if data.damage and data.damage.from and not data.damage.from.dead then
        defeat = data.damage.from
      end
      local otherplayers = endlPrac:getOPlayers(body)
      local ldiefriends = endlPrac:getLDieFriends()
      local othercamps = #otherplayers
      if #ldiefriends > 0 then
        endlPrac:reLayerFriends(ldiefriends)
      end
      --层主死亡层数+1并复活加强
      if body.role == "lord" then
        -- dbg()
        endlPrac:removeLayerBoss(defeat)
        endlPrac:changeLayer(1)
      end
      endlPrac:bury(body)
      --清除相关技能
      endlPrac:removeRelateSkills(body)
      --转变武将且复活
      local layer = endlPrac:getLayer()
      local haveboss = endlPrac:getLayerBoss()
      local newgeneral = endlPrac:changeGeneral(body,nil,haveboss)
      if not newgeneral then
        room:doBroadcastNotify("ShowToast", "将池耗尽")
        room:gameOver("rebel")
        return
      end
      --删除复活前技能
      endlPrac:removeOldSkills(newgeneral,body)
      --刷新最大maxhp与hp
      local maxhpcfg = {4,3,2}
      local basic = maxhpcfg[othercamps]
      local cal_add = math.floor(layer / (basic and basic or 2))
      if body.role ~= "lord" then
        cal_add = math.floor(cal_add / 4)
      end
      if haveboss then
        cal_add = math.floor(cal_add * 2.5)
      end
      if cal_add > 0 then
        endlPrac:updateMax(body,cal_add)
      end
      --获得关卡技能
      if body.role == "lord" then
        endlPrac:getLaySkills(body)
      end
      --层主或层队友每过n关获得随机技能
      local n = endlPrac:getRskiNum()
      if body.role ~= "lord" then
        n = math.floor(n/2)
      end
      if n > 0 then
        endlPrac:getRandSkills(n,clonegenerals,body,false)
      end
      --刷新层数
      if body.role == "lord" then
        endlPrac:updateLayer(body,"@wj_layer")
        --通知其他角色层数
        endlPrac:notifyLayer("curlayerphase")
      end
      --摸等量手牌
      if body.role == "lord" then
        endlPrac:drawByRelife(body)
      else
        local ctw = endlPrac:getContiWin() + 1
        room:drawCards(body, 4 + (math.floor(layer/10)*2) + ctw * 2,self.name)
        endlPrac:otherPlayersDraw(1+(math.floor(layer/10)*2))
      end
      --------------------------------------------------------------------
      ----------------------玩家处理--------------------------------------
      --------------------------------------------------------------------
      endlPrac:gainRandGold()
      endlPrac:meetPuYuan()
      endlPrac:addContiWin(1)
      --每3+（层数/10）关获得一次奖励
      local step = math.floor(layer / 10)
      local step_n = layer % 10
      local cal_step = step_n % (3 + step)
      if cal_step ~= 0 and not istest then
        --连胜超过一定回合结束当前阶段
        endlPrac:handleContiWin()
        return
      end
      if body.role ~= "lord" then return end
      --玩家潘多拉技能重置
      endlPrac:resetPdlSkills()
      --随机的奖励选项
      --开始选择
      endlPrac:layerRewards()
      --召唤潘多拉
      local call_n = 6 * #otherplayers
      endlPrac:callPanduola(body,call_n)
      --连胜超过一定回合结束当前阶段
      endlPrac:handleContiWin()
    elseif event == fk.GameStart then
      local room = player.room
      local logic = player.room.logic
      local endlPrac = logic.endlPrac
      local allgenerals = endlPrac.all_generals

      local otherplayers = endlPrac:getOPlayers(player,room)
      local othercamps = #otherplayers
      local selfcamps = #room.alive_players - othercamps
      --规则限制（至少1个人机，无尽武将列表）
      if not logic or not endlPrac or #allgenerals == 0 or othercamps / selfcamps > 3 then
        room:doBroadcastNotify("ShowToast", "没有人机或玩家与人机比超过3：1。游戏结束")
        room:gameOver(player.role)
        return
      end
      for _, p in ipairs(room.players) do
        if p.id > 0 then
          local chs = room:askForChoice(p, {"wjsl_title","wjsl_title1"}, "wjsl_tips", "wjsl_tips",true) or nil
          if not istest and not rm_general(allgenerals,p) then
            room:doBroadcastNotify("ShowToast", Fk:translate(p.general).."不在白名单。游戏结束。请选择欢杀非神将")
            room:gameOver(player.role)
            return
          end 
        end
      end
      local gamedata = table.clone(initGameData)
      if othercamps == 1 then
        local selmodel = room:askForChoice(otherplayers[1], {"hardmodel","godmodel"}, "selmodel", "selmodel",true)
        if selmodel == "godmodel" then
          gamedata.i_layer = 50
          gamedata.initgold = 5
          gamedata.rewd_intval = {{12,1,4},{25,2,5},{100,10,10}}
          gamedata.hardmodel = selmodel
        end
      end
      --PVE
      local lord = {}
      for _, p in ipairs(room.players) do
        if p.role == "rebel" then
          table.insertIfNeed(lord,p)
        end
      end
      for _, p in ipairs(lord) do
        local choices = {"pvebuff1","pvebuff2","pvebuff3","nopvebuff"}
        p.request_data = json.encode({choices, choices, "tshu__buff", "#pvebuff-choice",true})
      end
      room:notifyMoveFocus(room.alive_players,"tshu__buff")
      room:doBroadcastRequest("AskForChoice", lord)
  
      for _, p in ipairs(lord) do
        local choice
        if p.reply_ready then
          choice = p.client_reply
        else
          p.client_reply = "pvebuff2"
          choice = "pvebuff2"
        end
        room:sendLog{
          type = "#tshu__buff-quest",
          from = p.id,
          arg = choice,
        }
        if choice == "pvebuff1" then
          room:setPlayerMark(p,"tshu__buff1",1)
          room:setPlayerMark(p,"tshu__buff2",1)
        elseif choice == "pvebuff2" then
          room:setPlayerMark(p,"tshu__buff1",1)
          room:setPlayerMark(p,"tshu__buff3",1)
        elseif choice == "pvebuff3" then
          room:setPlayerMark(p,"tshu__buff3",1)
          room:setPlayerMark(p,"tshu__buff4",1)
        end
      end
      --需要将灵
      
      local jlmark = {"tshujl__zhugeguo","tshujl__lingjv","tshujl__zhouyu","tshujl__caoying","tshujl__guansuo","tshujl__nianshou","tshujl__zhaoxiang","tshujl__xiaosha","tshujl__caochun","tshujl__guanyu","tshujl__zhaoyun"}
      local jle = {}
      for _, p in ipairs(lord) do
      local jl = table.random(jlmark,5)
      local skills = {}
      for _, s in ipairs(jl) do
        room:setPlayerMark(p,s,0)
        table.insert(skills,{s})
      end
  
      p.request_data = json.encode({
        path = "packages/tshu/qml/ChooseGeneralSkillsBox.qml",
        data = {
          jl,skills, 1, 1, "#jl-choice", true
        },
      })
      p.default_reply = ""
    end
    room:doBroadcastRequest("CustomDialog", lord)
    for _, p in ipairs(lord) do
      local j = p.reply_ready and json.decode(p.client_reply) or p.default_reply
      if j and j ~= "" and Fk:translate(table.concat(j)) ~= "" then
    room:notifySkillInvoked(p,table.concat(j),"drawcard")
    for _, s in ipairs(Fk.generals[table.concat(j)].skills) do
      p:broadcastSkillInvoke(s.name)
      break
    end
    room:setPlayerMark(p,table.concat(j),1)
    table.removeOne(jlmark,table.concat(j))
    table.insertIfNeed(jle,table.concat(j))
    end
  end
    if #jle > 0 then
      room:setBanner("@&tshu__jl",jle)
    end
      endlPrac:initData(player,gamedata)
      endlPrac:layerRewards()
  
    elseif event == fk.GameOverJudge then
      room:setTag("SkipGameRule", true)
    elseif event == fk.TurnStart then
      -- body
      local room = player.room
      local lord = room:getLord()
      local endlPrac = lord.room.logic.endlPrac
      endlPrac:setContiWin(0)
      if player.id < 0 and player.role == "loyalist" then
        room:addPlayerMark(player,"zhenfenaddi")
        local zhenfen = player:getMark("zhenfenaddi")
        if zhenfen % 2 == 0 then
          local addchc = {"@df_lingxin","@slash_dmg"}
          room:addPlayerMark(player,table.random(addchc))
        end
      end
    elseif event == fk.DrawNCards then
      -- body
      -- local room = player.room
      local endlPrac = player.room.logic.endlPrac
      local haveboss = endlPrac:getLayerBoss()
      if haveboss then
        local layer = endlPrac:getLayer()
        local value = math.ceil(layer / 10) * 2
        data.n = data.n + value
      end
    end
  end,
}
Fk:addSkill(wjsl_rule)

local CurPhaseEnd = function (target,event)
  if target.phase == Player.NotActive then
      return
  end
  local room = target.room
  local mark = target:getMark("@wjsl_zhenta_num")
  mark = mark - 1
  room:setPlayerMark(target,"@wjsl_zhenta_num",mark)
  if mark < 1 then
    room:doBroadcastNotify("ShowToast", "结束当前阶段")
    local current = target.room.logic:getCurrentEvent()
    local usecard_event = current:findParent(event)
    if not usecard_event then return end
    local phase_event = usecard_event:findParent(GameEvent.Phase)
    if not phase_event then return end
    usecard_event:addExitFunc(function()
      phase_event:shutdown()
    end)
  end
end

--镇塔
local wjsl_zhenta = fk.CreateTriggerSkill{
  name = "wjsl_zhenta",
  frequency = Skill.Compulsory,
  events = {fk.TurnStart,fk.TurnEnd,fk.CardUseFinished,fk.AfterSkillEffect},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self.name) then
      return
    end
    if player == target then
      return
    end
    -- return player.room.current == target
    if event == fk.TurnStart or event == fk.TurnEnd then
      return player.room.current == target
    elseif event == fk.CardUseFinished then
      return true
    else
      return data.name == "wjsl_zhujia" and data.cost_data
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TurnStart then
      local maxhp = target.maxHp
      if maxhp <= 5 then
        local value = 0
        if target.id > 0 and target.role == "rebel" then
          value = target.maxHp * 2
        end
        if target.id < 0 and target.role == "loyalist" then
          value = target.maxHp * 3
        end
        room:setPlayerMark(target,"@wjsl_zhenta_num",value)
      else
        local value = 0
        if target.id > 0 and target.role == "rebel" then
          value = math.min(10+(maxhp-5),15)
        end
        if target.id < 0 and target.role == "loyalist" then
          value = 15
        end
        room:setPlayerMark(target,"@wjsl_zhenta_num", value)
      end
      local shield_mark = target:getMark("wjsl_zhujia_shield") 
      if shield_mark > 0 then
        room:changeShield(target, -shield_mark)
        room:setPlayerMark(target,"wjsl_zhujia_shield",0)
      end
    elseif event == fk.CardUseFinished then
      CurPhaseEnd(target,GameEvent.UseCard)
    elseif event == fk.TurnEnd then
      -- body
      room:setPlayerMark(target,"@wjsl_zhenta_num",0)
    else
      CurPhaseEnd(target,GameEvent.SkillEffect)
    end
  end,
}
Fk:addSkill(wjsl_zhenta)

--塔震
local wjsl_tazhen = fk.CreateTriggerSkill{
  name = "wjsl_tazhen",
  anim_type = "masochism",
  frequency = Skill.Compulsory,
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self.name) then
      return
    end
    return player == target and not player.dead and data.from and data.from~=player and data.damage > 1 and not data.from.dead
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local hands = data.from:getCardIds{Player.Hand}
    if #hands > data.damage then
      local randcards = table.random(hands,data.damage)
      room:throwCard(randcards,self.name,data.from,player)
    else
      data.from:throwAllCards("he")
    end
    room:damage{from = player,to = data.from,damage = data.damage,skillName = self.name}
  end,
}
Fk:addSkill(wjsl_tazhen)

local zhenfen_maxhands = fk.CreateMaxCardsSkill{
  name = "#zhenfen_maxhands",
  correct_func = function (self, player)
    if player:hasSkill("wjsl_zhenfen") and player:getMark("@df_lingxin") > 0 then
      return player:getMark("@df_lingxin")
    end
  end,
}

--振奋
local wjsl_zhenfen = fk.CreateTriggerSkill{
  name = "wjsl_zhenfen",
  frequency = Skill.Compulsory,
  anim_type = "offensive",
  events = {fk.TargetSpecifying,fk.DrawNCards,fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self.name) then
      return
    end
    if event == fk.TargetSpecifying then
      if player == target and data.card then
        if data.card.trueName == "slash" and player:getMark("@slash_dmg") > 0 then
          self.cost_data = "@slash_dmg"
          return true
        end
        if data.card.type == Card.TypeTrick and data.card.is_damage_card and player:getMark("@trick_dmg") > 0 then
          self.cost_data = "@trick_dmg"
          return true
        end
      end
    elseif event == fk.DrawNCards then
      return player:getMark("@df_lingxin") > 0 and player == target
    elseif event == fk.TurnStart then
      return player:getMark("@shieldnum") > 0 and player:getMark("@shieldnum") - player.shield > 0
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.TargetSpecifying then
      data.additionalDamage = (data.additionalDamage or 0) + player:getMark(self.cost_data)
      self.cost_data = nil
    elseif event == fk.DrawNCards then
      data.n = data.n + player:getMark("@df_lingxin")
    elseif event == fk.TurnStart then
      player.shield = player:getMark("@shieldnum")
      room:broadcastProperty(player, "shield")
    end
  end,
}
wjsl_zhenfen:addRelatedSkill(zhenfen_maxhands)
Fk:addSkill(wjsl_zhenfen)

--铸甲
local wjsl_zhujia = fk.CreateActiveSkill{
    name = "wjsl_zhujia",
    -- anim_type = "support",
    min_card_num = 1,
    max_card_num = 2,
    can_use = function(self,player)
      return player:hasSkill(self.name) and player.phase == Player.Play and player:usedSkillTimes(self.name, Player.HistoryTurn) < math.ceil(player:getMark("curlayerphase") / 10) * 2 + 1
    end,
    card_filter = function(self, to_select, selected)
      local card = Fk:getCardById(to_select)
      if #selected == 0 then
        if card.type == Card.TypeEquip or card.name == "jink" then
          return true
        end
      elseif #selected == 1 then
        if Self.shield >= 5 then
          return
        end
        if Fk:getCardById(selected[1]).name == "jink" then
          return card.name == "jink"
        end
        if Fk:getCardById(selected[1]).type == Card.TypeEquip then
          return card.type == Card.TypeEquip
        end
      elseif #selected == 2 then
        return false
      end
    end,
    target_filter = function(self, to_select, selected)
        return false
    end,
    on_use = function(self, room, effect)
        local player = room:getPlayerById(effect.from)
        self.cost_data = false
        if #effect.cards == 1 then
          room:recastCard(effect.cards, player, self.name)
        else
          self.cost_data = true
          room:throwCard(effect.cards,self.name,player,player)
          room:changeShield(player, 1)
          room:addPlayerMark(player,"wjsl_zhujia_shield",1)
        end
        
    end,
}
Fk:addSkill(wjsl_zhujia)

--通神
local tongshen = fk.CreateTriggerSkill{
  name = "joy__tongshen",
  events = {fk.BeforeTurnStart},
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    return target ~= player and player:hasSkill(self)  and player:usedSkillTimes(self.name, Player.HistoryRound) <= 1 
  end,
  on_use = function(self, event, target, player, data)
    player.room:doIndicate(player.id, {target.id})
    player:gainAnExtraTurn(true)
    player.room:setPlayerMark(player,"joy__tongshen",1)
  end
}
local tongshen_prohibit = fk.CreateProhibitSkill{
  name = "#tongshen_prohibit",
  frequency = Skill.Compulsory,
  is_prohibited = function(self, from, to, card)
    if to:hasSkill(self) then
      return card.sub_type == Card.SubtypeDelayedTrick
    end
  end,
  prohibit_pindian = function(self, from, to)
    return to:hasSkill(self)
  end
}
tongshen:addRelatedSkill(tongshen_prohibit)
Fk:addSkill(tongshen)

local wjsl_mode = fk.CreateGameMode{
  name = "wjsl_mode",
  minPlayer = 2,
  maxPlayer = 6,
  rule = wjsl_rule,
  logic = wjsl_getLogic,
  whitelist = table.clone(whilecards),
  winner_getter = function(self, victim)
    local room = victim.room
    local alive = table.filter(room.alive_players, function(p)
      return not p.surrendered
    end)
    if #alive ~= 1 then return "" end
    return alive[1].role
  end,
  surrender_func = function(self, playedTime)
    local surrenderJudge = { { text = "time limitation: 10s", passed = playedTime >= 10 } }
    if Self.role ~= "lord" then
      table.insert(surrenderJudge, { text = "1v1: left you alive", passed = true})
    end
    return surrenderJudge
  end,
}

Fk:loadTranslationTable{
  ["wjsl_mode"] = "巅峰神塔",
  ["#wjsl_rule"] = "巅峰神塔",
  ["@wj_layer"] = "层数:",
  ["Max"] = "最终层",
  ["@@godmodel"] = "速通模式",

  ["wjsl_zhenta"] = "镇塔",
  [":wjsl_zhenta"] = "锁定技，每名其他角色回合开始时，使用牌会计入次数，计数为最大体力值的两倍（队友忠臣人机是3倍，最多15）（当玩家最大体力值超过5，计数只+1且最多为15），使用卡牌结算后或者因【铸甲】获得护甲，计数-1。当计数为0时结束当前阶段。",

  ["wjsl_zhujia"] = "铸甲",
  [":wjsl_zhujia"] = "出牌阶段限制（层数/10|向上取整）* 2次。你可以重铸1张【闪】或者【装备】牌，也可以丢弃两张【闪】或【装备】牌获得1枚护甲（最多为5护甲），该护甲在你下回合开始时如果还存在则失去先前获得数量",

  ["wjsl_tazhen"] = "塔震",
  [":wjsl_tazhen"] = "锁定技，当你受到其他角色大于1伤害后，你令伤害来源弃随机X张牌并受到X点伤害（X为受到伤害值）",

  ["df_fengkuang"] = "疯狂",
  [":df_fengkuang"] = "锁定技，当你体力为最大体力一半以及一半以下，你无视被禁用卡与使用对目标的卡被禁技能规则且你使用牌造成伤害翻倍（此技能只对人机有效）",

  ["joy__tongshen"] = "通神",
  [":joy__tongshen"] = "锁定技；<br>①每轮限一次，当一名其他角色的回合开始时，你获得一个额外的回合。<br>②你无法成为延时锦囊牌的目标。<br>③若你为层主，发动过“通神”后你将无视被禁用卡与使用对目标的卡被禁技能规则。",

  ["@wjsl_zhenta_num"] = "计数",

  ["pdlboxreset"] = "魔盒：技能重置",

  ["#skills-choice"] = "随机选项选择",
  ["#relife-choice"] = "重生玩家请选择",
  ["#rstskills_1"] = "重置魔盒技能（需要5金币）",
  ["#rstskills_2"] = "重置魔盒技能（需要7金币）",
  ["#rstskills_3"] = "重置魔盒技能（需要10金币）",
  ["#rstskills_4"] = "重置魔盒技能（需要12金币）",
  ["#rstskills_5"] = "重置魔盒技能（需要15金币）",
  ["#getBossSkills-choice"] = "获取神将技能",
  ["time limitation: 10s"] = "游戏长达10秒",
  ["1v1: left you alive"] = "任何时候，任何人数都可以投降",

  ["gaingold"] = "获得金币",
  [":gaingold"] = "获得金币随机40~70，层数越高随机金币下限有一定提升",
  ["maxhp"] = "成长",
  [":maxhp"] = "随机增加体力与最大体力值",
  ["angelbless"] = "天使祝福",
  [":angelbless"] = "天使祝福让你摸体力上限的手牌，回满体力，额外获得一层标记增益或者些许金币",
  ["magicbox"] = "魔盒的交易",
  [":magicbox"] = "你获得随机1-3【魔盒】标记（当获得该标记时，获得等量的随机技能。每到选项奖励可以用金币重置【魔盒】标记技能）",
  ["slash_dmg_sel"] = "【振奋】强化",
  [":slash_dmg_sel"] = "【振奋】强化【杀】，【杀】指向目标伤害+1",
  ["trick_dmg_sel"] = "【振奋】强化",
  [":trick_dmg_sel"] = "【振奋】强化【伤害锦囊】，【伤害锦囊】指向目标伤害+1",
  ["lingxin"] = "凌心",
  [":lingxin"] = "你获得随机1-3【凌心】标记，此标记能够使你的摸牌阶段摸牌数和手牌上限额外增加该标记值",
  ["shieldnum"] = "护盾",
  [":shieldnum"] = "你获得随机1-2随机【护甲+】标记，此标记能够在每回合开始把护甲叠到对应标记值",
  ["relife"] = "重生",
  [":relife"] = "你可以选择一名死亡玩家复活",
  ["guard_angel"] = "守护天使",
  [":guard_angel"] = "你活得“守护天使”标记，当你死亡时候可以满血复活并摸等量的牌，结束当前玩家回合阶段",
  ["rsetrwd_1"] = "重置奖励",
  [":rsetrwd_1"] = "可以花费20金币重置一次奖励",
  ["rsetrwd_2"] = "重置奖励",
  [":rsetrwd_2"] = "可以花费30金币重置一次奖励",
  ["rsetrwd_3"] = "重置奖励",
  [":rsetrwd_3"] = "可以花费40金币重置一次奖励",

  ["@@guardangle"] = "守护天使",
  ["@slash_dmg"] = "杀+",
  ["@trick_dmg"] = "锦囊+",
  ["@pdlbox"] = "魔盒+",
  ["@df_lingxin"] = "凌心+",
  ["@shieldnum"] = "护甲+",
  ["@gold_num"] = "金币:",

  ["pyshop_buyitems"] = "购买装备",
  ["pyshop_cellskills"] = "出售技能",
  ["#puyuanShop-choice"] = "浦元铁匠铺",
  ["#puyuanShop-buyeuips"] = "购买装备药水",
  ["#puyuanShop-cellskills"] = "出售技能",
  ["Exist"] = "离开",

  ["wjsl_zhenfen"] = "振奋",
  [":wjsl_zhenfen"] = "锁定技，【杀】或者【锦囊】造成伤害值+获得强化的标记值",

  [":需要"] = "给我来一个！",
  [":不需要"] = "我只想体验纯净的PVE",

  ["godmodel"] = "<font color='blue'>通神之路</font>",
  [":godmodel"] = "<font color='yellow'>适合快节奏玩家</font>，从第50层启动，连续挑战20名boss后进入71层最终挑战，初始获得的奖励收益翻n倍。",
  ["hardmodel"] = "<font color='yellow'>正常模式</font>",
  [":hardmodel"] = "<font color='yellow'>适合正常玩家</font>，从零开始，前50层每10层一个boss，50层以后进入<font color='blue'>【通神之路】</font>，此模式可获得的加成更加实用<br/><font color='red'>此模式搬运自huosan服风车大佬制作的模式，私自修改仅供娱乐。</font>",
  ["selmodel"] = "难度选择",
  ["wjsl_tips"] = "新手提示",
  ["wjsl_title"] = "新手提示",
  [":wjsl_title"] = "<br/>1.塔层共71层，难度逐层递增。下一层复活的层主摸牌数是根据玩家手牌、连胜次数来计算。<br/>2.玩家连胜5次将终结其阶段(超过40层改为4)，如果是多人玩家层主还会获得一个额外的回合。<br/>3.请不要摸牌过多以至于牌堆为0平局<font color='blue'>(建议商店购买技能【蛮王】）</font>。",
  ["wjsl_title1"] = "浦沅商店",
  [":wjsl_title1"] = "<font color='red'>此模式搬运自huosan服风车大佬制作的模式，私自修改仅供娱乐。</font><br/>层数大于10有概率遇到，可以买药水、稀有装备、技能。也可以卖技能（潘多拉技能除外）",
  [":wjsl_mode"] = desc_wjsl_mode,
}

return wjsl_mode